
#ifndef Q_DEFS

#define Q_DEFS

/* quad.h:
 *	defines quad-edge data structure.
 * Modified from Tien Truong by Jack Snoeyink, 18 sept 92.
 */

#include "geom.h"

#define Q_MASK_EDGE (sizeof(QUAD) - 1)
#define Q_MASK_ROT  (0xffffffff ^ Q_MASK_EDGE)


#define Q_RotN(e, n)		/* Pointer manipulation for Qedge rotation */\
  (Qedge *)(((unsigned int) e & Q_MASK_ROT)                                  \
	    | (((unsigned int) e + n) & Q_MASK_EDGE))

#define Q_Addr(e)		/* Get zero edge of quad (for new/dispose) */\
	(Qedge *) ((unsigned int) e & Q_MASK_ROT)


/* Q_ROT:
 *      Edge function Rot:   (e, r).Rot  = (e, r+1)
 */
#define Q_ROT(e)		(Q_RotN(e, sizeof(Qedge)))


/* Q_SYM:
 *	Edge function Sym:   (e, r).Sym  = (e, r+2)
 */
#define Q_SYM(e)		(Q_RotN(e, 2*sizeof(Qedge)))


/* Q_IROT:
 *	Edge function IRot:  (e, r).IRot = (e, r+3)
 */
#define Q_IROT(e)		(Q_RotN(e, 3*sizeof(Qedge)))


/* Q_ONEXT:
 *	Edge function Onext: (e, r).Onext = e[r].Next
 */
#define Q_ONEXT(e)		((e)->next)


/* Q_OPREV:
 *	Edge function Oprev: (e, r).Oprev = (e[r+1].next) Rot
 */
#define Q_OPREV(e)		(Q_ROT( Q_ONEXT( Q_ROT(e))))


/* Q_DNEXT:
 *	Edge function Dnext: e.Dnext = e.Sym.Onext.Sym
 */
#define Q_DNEXT(e)		(Q_SYM( Q_ONEXT( Q_SYM(e))))


/* Q_DPREV:
 *	Edge function Dprev: e.Dprev = e.IRot.Onext.IRot
 */
#define Q_DPREV(e)		(Q_IROT( Q_ONEXT( Q_IROT(e))))


/* Q_LNEXT:
 *	Edge function Lnext: e.Lnext = e.IRot.Onext.Rot
 */
#define Q_LNEXT(e)		(Q_ROT( Q_ONEXT( Q_IROT(e))))


/* Q_LPREV:
 *	Edge function Lprev: e.Lprev = e.Onext.Sym
 */
#define Q_LPREV(e)		(Q_SYM( Q_ONEXT(e)))


/* Q_RNEXT:
 *	Edge function Rnext: e.Rnext = e.Rot.Onext.IRot
 */
#define Q_RNEXT(e)		(Q_IROT( Q_ONEXT( Q_ROT(e))))


/* Q_RPREV:
 *	Edge function Rprev: e.Rprev = e.Sym.Onext
 */
#define Q_RPREV(e)		(Q_ONEXT( Q_SYM(e)))


/* Q_ORG:
 *	e.Org = e.data
 */
#define Q_ORG(e)		((e)->data)


/* Q_DEST:
 *	e.Dest = e.Sym.Org
 */
#define Q_DEST(e)		(Q_ORG( Q_SYM(e)))


/* Q_LEFT:
 *	e.Left = e.IRot.Org
 */
#define Q_LEFT(e)		(Q_ORG( Q_IROT(e)))


/* Q_RIGHT:
 *	e.Right = e.Rot.Org
 */
#define Q_RIGHT(e)		(Q_ORG( Q_ROT(e)))

/* Q_MARK: 
 *      An integer marker for traversing the structure.
 */
#define Q_MARK(e)               ((e)->mark)


/* edge type:
 *	An edge of the quad-edge structure, consisting of a data
 *	field for e.Org, and a next pointer to the next edge of the
 *	ring, and a mark.
 */

typedef struct Qedge {
    POINT *data;		/* data field associated w/ e.org 	*/
    int mark;			/* marker for traversal */
    int tmp;
    struct Qedge *next;		/* reference to next edge of ring	*/
} Qedge;

typedef Qedge QUAD[4];

#ifdef __cplusplus
extern "C" {
#endif

extern QUAD *Quadlist;

extern void     Q_Init(int);
extern Qedge	*Q_MakeEdge(QUAD **);
extern void	Q_Splice(Qedge *, Qedge *);

extern Qedge *MakeQedge(POINT *, POINT *, POINT *, POINT *);

#ifdef __cplusplus
}
#endif

#endif